package com.sy.olddriver.utils;

import com.sy.olddriver.constant.AppConstant;
import com.sy.olddriver.entity.User;
import com.sy.olddriver.exception.OldDriverException;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.security.Key;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * Redis操作工具类
 *
 * @author Administrator
 */
public class RedisUtils {
    private static JedisPool jedisPool;

    private RedisUtils() {

    }

    static {
        Properties props = PropertiesUtils.loadProperties("redis.properties");

        //创建连接池的配置信息对象
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //最大总连接数
        jedisPoolConfig.setMaxTotal(Integer.parseInt(props.getProperty("redis.maxTotal")));
        //最大空闲连接数
        jedisPoolConfig.setMaxIdle(Integer.parseInt(props.getProperty("redis.maxIdle")));

        //创建连接池对象
        jedisPool = new JedisPool(jedisPoolConfig, props.getProperty("redis.host"), Integer.parseInt(props.getProperty("redis.port")));
    }


    /**
     * 封装了Redis中使用set命令进行序列化保存对象的操作
     *
     * @param key Redis中的key
     * @param obj 要序列化保存到Redis中的对象
     * @return Redis操作后的结果
     */
    public static boolean set(String key, Serializable obj) {
        try (Jedis jedis = jedisPool.getResource()) {
            return StringUtils.equals(AppConstant.REDIS_OK_RESULT, jedis.set(key.getBytes(), SerializationUtils.serialize(obj)));
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * 从Redis中反序列化得到之前序列化保存的对象
     *
     * @param key redis中的key
     * @param <T> 反序列化后对象的类型
     * @return 反序列化以后的结果
     */
    public static <T> T getObj(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            byte[] bytes = jedis.get(key.getBytes());
            if (!ArrayUtils.isEmpty(bytes)) {
                return (T) SerializationUtils.deserialize(bytes);
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }


    /**
     * 设置Redis中key的过期时间
     *
     * @param key    Redis中的key
     * @param expire 过期时间（单位：s）
     * @return 是否修改成功
     */
    public static boolean expire(String key, int expire) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.expire(key, expire) > 0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * 删除Redis中key对应的数据
     *
     * @param keys 键值（可以有1到任意多个）
     * @return 删除操作是否成功
     */
    public static boolean del(String... keys) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.del(keys) > 0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }


    /**
     * string类型的set操作
     *
     * @param key   键名
     * @param value 键值
     * @return 是否操作成功
     */
    public static boolean set(String key, String value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return StringUtils.equals(AppConstant.REDIS_OK_RESULT, jedis.set(key, value));
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * string类型的get操作
     *
     * @param key 键名
     * @return 返回的键值
     */
    public static String get(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(key);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * list类型的lpush方法
     *
     * @param key    键名
     * @param values 要放进去的元素的值
     * @return 返回的键值
     */
    public static boolean lpush(String key, String... values) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.lpush(key, values) > 0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * list中的lrem操作
     *
     * @param key   要操作的list
     * @param count 要删除的元素个数
     * @param value 要删除的元素的值
     * @return 是否删除成功
     */
    public static boolean lrem(String key, Long count, String value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.lrem(key, count, value) > 0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * 获取list中元素的个数
     *
     * @param key 键值
     * @return list的长度
     */
    public static Long llen(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.llen(key);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * list中的lrange命令
     *
     * @param key   键名
     * @param start 起始索引
     * @param end   结束索引（最大为长度-1）
     * @return 获取到的指定索引访问的元素
     */
    public static List<String> lrange(String key, Long start, Long end) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.lrange(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * 封装了hash类型中的hincrBy命令
     *
     * @param key   hash类型在redis中的key
     * @param field hash类型中要修改的属性名
     * @param value hash类型中属性要修改的增量值
     * @return 属性更新以后的对应的value的新值
     */
    public static Long hincrBy(String key, String field, Long value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hincrBy(key, field, value);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * redis中的exists命令
     *
     * @param key 要判断是否存在的键的名字
     * @return 是否存在的结果
     */
    public static boolean exists(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.exists(key);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }


    /**
     * hash类型的hgetall命令
     *
     * @param key hash类型的键名
     * @return hash类型中所有的键值
     */
    public static Map<String, String> hgetAll(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hgetAll(key);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * hash类型中的hdel命令
     *
     * @param key    hash类型在redis中的key
     * @param fields hash类型中要被删除的属性的名字
     * @return 删除操作是否成功
     */
    public static boolean hdel(String key, String fields) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hdel(key, fields) > 0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }


    /**
     * hash类型中的hset命令
     *
     * @param key   hash类型在redis中的key
     * @param field hash类型中要设置的属性名
     * @param value hash类型中属性要设置的值
     * @return 属性的设置操作是否成功
     */
    public static boolean hset(String key, String field, String value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hset(key, field, value) > 0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

    /**
     * string类型的incr命令
     *
     * @param key string类型的键
     * @return 自增后的结果
     */
    public static Long incr(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.incr(key);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("系统异常");
        }
    }

}
